package com.schd.base.model;

import com.alibaba.fastjson.JSONArray;
import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.schd.base.utils.BeanUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.data.domain.Range;
import org.springframework.data.jpa.domain.Specification;

/**
 * @author 陈刚
 * @version 1.0
 * @project ZNSM
 * @package com.haorui.base.core.model
 * @createDate 2017-08-18 15:33
 * @modfiyDate
 * @function 搜索条件拼接
 */
public class Search<E>  {
    private SearchCondition[] searchConditions;
    private Class<E> tranClass;
    public Search(Class<E> eClass) {
        this.tranClass=eClass;
    }

    public Search<E> setSearchConditions(SearchCondition... searchConditions){
        this.searchConditions=searchConditions;
        return this;
    }
    public Specification<E> searchBuild(){
        if(ArrayUtils.isEmpty(searchConditions)){
            return null;
        }
        PredicateBuilder<E> predicateBuilder=Specifications.and();
        for (SearchCondition searchCondition : searchConditions) {
            if(searchCondition.getValue()==null){
                continue;
            }
            searchCondition.setValue(BeanUtil.convertValue(tranClass,searchCondition.getPro(),searchCondition.getValue()));
            switch (searchCondition.getOper()){
                case EQ:
                    predicateBuilder=predicateBuilder.eq(searchCondition.getPro(),searchCondition.getValue());
                    break;
                case NOTEQ:
                    predicateBuilder=predicateBuilder.ne(searchCondition.getPro(),searchCondition.getValue());
                    break;
                case IN:
                    if(searchCondition.getValue() instanceof JSONArray){
                        JSONArray jsonArray=(JSONArray) searchCondition.getValue();
                        if(!jsonArray.isEmpty()){
                            predicateBuilder=predicateBuilder.in(searchCondition.getPro(), jsonArray.toArray());
                        }
                    }else{
                        predicateBuilder=predicateBuilder.in(searchCondition.getPro(), (Object[]) searchCondition.getValue());
                    }

                    break;
                case NOTIN:
                    predicateBuilder=predicateBuilder.notIn(searchCondition.getPro(),searchCondition.getValue());
                    break;
                case LTE:
                    if(searchCondition.getValue() instanceof Comparable){
                        predicateBuilder=predicateBuilder.lt(searchCondition.getPro(),(Comparable)searchCondition.getValue());
                    }
                    break;
                case GTE:
                    if(searchCondition.getValue() instanceof Comparable){
                        predicateBuilder=predicateBuilder.gt(searchCondition.getPro(),(Comparable)searchCondition.getValue());
                    }
                    break;
                case LIKE:
                    if(searchCondition.getValue() instanceof String){
                        predicateBuilder=predicateBuilder.like(searchCondition.getPro(),"%"+searchCondition.getValue()+"%");
                    }
                    break;
                case NOTLIKE:
                    if(searchCondition.getValue() instanceof String){
                        predicateBuilder=predicateBuilder.notLike(searchCondition.getPro(),"%"+searchCondition.getValue()+"%");
                    }
                    break;
                case BETWEEN:
                    if(searchCondition.getValue().getClass().isArray()){
                        Object[] objects=(Object[]) searchCondition.getValue();
                        if(objects.length==2){
                            if(objects[0] instanceof Comparable && objects[1] instanceof Comparable){
                                predicateBuilder=predicateBuilder.between(searchCondition.getPro(),new Range<>((Comparable)objects[0],(Comparable)objects[1]));
                            }
                        }
                    }
            }
        }
        return predicateBuilder.build();
    }

}
